#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
 
void handler(int signum)
{
    while(true)
    {
        pid_t n = waitpid(-1, nullptr, WNOHANG);    //若回收的进程不处于僵尸状态，则不会阻塞在此处，返回值为0
        if (n == 0) 
        {
            break;
        }
        else if (n < 0)
        {
            std::cout << "waitpid error" << std::endl;
            break;
        }
    }
}
 
int main()
{
    signal(SIGCHLD, SIG_IGN);
 
    for (int i = 0; i < 10; i++)
    {
        pid_t id = fork();
        if (id == 0)
        {
            sleep(3);
            std::cout << "I am child" << std::endl;
            if (i < 6)
                exit(1);
            else
                pause();
        }
    }
 
    while(true)
    {
        std::cout << "I am father" << std::endl;
        sleep(1);
    }
    return 0;
}








// #include <iostream>
// #include <unistd.h>
// #include <cstdio>
// #include <sys/types.h>
// #include <sys/wait.h>
// #include <signal.h>

 
// void handler(int signum)
// {
//     std::cout << "signum: " << signum << std::endl;
// }
 
// int main()
// {
//     signal(SIGCHLD, handler);
 
//     pid_t id = fork();
//     if (id == 0)
//     {
//         std::cout << "I am child" << std::endl;
//         sleep(1);
//         exit(1);
//     }
 
//     waitpid(id, nullptr, 0);
//     return 0;
// }

// volatile int flag = 0;
 
// void handler(int signum)
// {
//     std::cout << "更改全局变量flag -> 1" << std::endl;
//     flag = 1;
// }
 
// int main()
// {
//     signal(2, handler);
 
//     while(!flag);
//     std::cout << "process quit normal! " << std::endl;
//     return 0;
// }
 
// void handler(int signum)
// {
//     std::cout << "hello signal: " << signum << std::endl;
//     while(true)
//     {
//         sigset_t pending;
//         sigpending(&pending);
//         for (int i = 31; i >= 1; i--)
//         {
//             if (sigismember(&pending, i))
//             {
//                 std::cout << "1";
//             }
//             else
//             {
//                 std::cout << "0";
//             }
//         }
//         std::cout << std::endl;
//         sleep(1);
//     }
//     // exit(0);
// }
 
// int main()
// {
//     struct sigaction act, oact;
//     act.sa_handler = handler;
//     sigaction(SIGINT, &act, &oact);
 
//     while(true)
//     {
//         std::cout << "hello world" << std::endl;
//         sleep(1);
//     }
    
//     return 0;
// }

// void PrintPending(sigset_t& pending)
// {
//     std::cout << "current process[" << getpid() << "]的pending: ";
//     //打印每一个bit位信号情况
//     for (int signo = 31; signo >= 1; signo--)
//     {
//         if (sigismember(&pending, signo))
//         {
//             std::cout << 1;
//         }
//         else
//         {
//             std::cout << 0;
//         }
//     }
//     std::cout << std::endl;
// }

// void handler(int signum)
// {
//     std::cout << signum << "号信号被递达!!!" << std::endl;
//     std::cout << "-----------------------" << std::endl;
//     sigset_t pending;
//     sigpending(&pending);
//     PrintPending(pending);
//     std::cout << "-----------------------" << std::endl;
// }


// int main()
// {
//     signal(2,handler);

//     // 1.屏蔽2号信号
//     sigset_t block_set,old_set;

//     // 将信号集初始化为没有任何信号
//     sigemptyset(&block_set);
//     sigemptyset(&old_set);

//     sigaddset(&block_set,SIGINT); // 给block_set信号集添加2号信号

//     // 将信号集合设置到进程的block表中，修改当前进程的内核block表，完成对2号信号的屏蔽
//     // 并且将原先进程的信号集给到old_set中
//     sigprocmask(SIG_BLOCK,&block_set,&old_set);

//     int cnt=10;
//     while(true){

//         // 2.获取当前进程的pending信号集
//         sigset_t pending;
//         sigpending(&pending);

//         // 3.打印pending信号集
//         PrintPending(pending);

//         cnt--;
//         // 4.解除对2号信号的屏蔽
//         if(cnt==0){
//             std::cout << "解除对2号信号的屏蔽!!!" << std::endl;

//             // 将原先的信号集合（没有任何信号）,设置掩码
//             // 就是不给任何信号设置掩码，等于解除任何信号的信号屏蔽字
//             sigprocmask(SIG_SETMASK, &old_set, &block_set);
//         }
//         sleep(1);
//     }
// }